<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>数字人管理系统 - 技术分析报告</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        
        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Microsoft YaHei', sans-serif;
            line-height: 1.6;
            color: #333;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
            padding: 20px;
        }
        
        .container {
            max-width: 1200px;
            margin: 0 auto;
            background: white;
            border-radius: 20px;
            box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
            overflow: hidden;
        }
        
        header {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 60px 40px;
            text-align: center;
        }
        
        header h1 {
            font-size: 2.5em;
            margin-bottom: 10px;
            text-shadow: 2px 2px 4px rgba(0,0,0,0.2);
        }
        
        header p {
            font-size: 1.2em;
            opacity: 0.9;
        }
        
        .content {
            padding: 40px;
        }
        
        .section {
            margin-bottom: 40px;
        }
        
        .section h2 {
            color: #667eea;
            font-size: 1.8em;
            margin-bottom: 20px;
            padding-bottom: 10px;
            border-bottom: 3px solid #667eea;
        }
        
        .section h3 {
            color: #764ba2;
            font-size: 1.4em;
            margin: 20px 0 10px 0;
        }
        
        .tech-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
            gap: 20px;
            margin: 20px 0;
        }
        
        .tech-card {
            background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
            padding: 20px;
            border-radius: 12px;
            border-left: 4px solid #667eea;
            transition: transform 0.3s, box-shadow 0.3s;
        }
        
        .tech-card:hover {
            transform: translateY(-5px);
            box-shadow: 0 10px 25px rgba(102, 126, 234, 0.3);
        }
        
        .tech-card h4 {
            color: #667eea;
            margin-bottom: 10px;
            font-size: 1.2em;
        }
        
        .feature-box {
            background: #f8f9fa;
            border-left: 4px solid #764ba2;
            padding: 15px 20px;
            margin: 15px 0;
            border-radius: 5px;
        }
        
        .code-block {
            background: #2d2d2d;
            color: #f8f8f2;
            padding: 20px;
            border-radius: 8px;
            overflow-x: auto;
            margin: 15px 0;
            font-family: 'Courier New', monospace;
            font-size: 0.9em;
        }
        
        .code-block .keyword {
            color: #c678dd;
        }
        
        .code-block .string {
            color: #98c379;
        }
        
        .code-block .comment {
            color: #5c6370;
            font-style: italic;
        }
        
        .diagram {
            background: white;
            border: 2px solid #667eea;
            padding: 20px;
            border-radius: 8px;
            margin: 20px 0;
            text-align: center;
        }
        
        .diagram-box {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 15px;
            margin: 10px;
            border-radius: 8px;
            display: inline-block;
            min-width: 150px;
        }
        
        ul {
            padding-left: 25px;
            margin: 10px 0;
        }
        
        li {
            margin: 8px 0;
        }
        
        .highlight {
            background: linear-gradient(120deg, #84fab0 0%, #8fd3f4 100%);
            padding: 2px 8px;
            border-radius: 4px;
            font-weight: bold;
        }
        
        .warning {
            background: #fff3cd;
            border-left: 4px solid #ffc107;
            padding: 15px;
            margin: 15px 0;
            border-radius: 5px;
        }
        
        .footer {
            background: #2d3748;
            color: white;
            padding: 30px;
            text-align: center;
        }
        
        .tags {
            display: flex;
            flex-wrap: wrap;
            gap: 10px;
            margin: 15px 0;
        }
        
        .tag {
            background: #667eea;
            color: white;
            padding: 5px 15px;
            border-radius: 20px;
            font-size: 0.9em;
        }
    </style>
</head>
<body>
    <div class="container">
        <header>
            <h1>数字人管理系统</h1>
            <p>技术架构与实现分析报告</p>
        </header>
        
        <div class="content">
            <!-- 项目概述 -->
            <div class="section">
                <h2>📋 项目概述</h2>
                <p>数字人管理系统是一个基于 <span class="highlight">React 19</span> 和 <span class="highlight">Three.js</span> 构建的现代化Web应用，集成了3D虚拟展厅、数据可视化、AI智能交互等核心功能。项目采用TypeScript编写，确保类型安全和代码质量。</p>
            </div>
            
            <!-- 核心技术栈 -->
            <div class="section">
                <h2>🛠️ 核心技术栈</h2>
                <div class="tech-grid">
                    <div class="tech-card">
                        <h4>⚛️ 前端框架</h4>
                        <p><strong>React 19.1.0</strong></p>
                        <p>最新版本的React框架，提供强大的组件化开发能力，支持Hooks、Context API等现代特性</p>
                    </div>
                    <div class="tech-card">
                        <h4>📝 开发语言</h4>
                        <p><strong>TypeScript 5.8.3</strong></p>
                        <p>提供静态类型检查，增强代码可维护性和开发体验</p>
                    </div>
                    <div class="tech-card">
                        <h4>⚡ 构建工具</h4>
                        <p><strong>Vite 6.3.5</strong></p>
                        <p>极速的开发服务器和优化的生产构建</p>
                    </div>
                    <div渲染="tech-card">
                        <h4>🎨 3D渲染</h4>
                        <p><strong>Three.js 0.180.0</strong></p>
                        <p>强大的WebGL 3D图形库，实现虚拟展厅</p>
                    </div>
                    <div class="tech-card">
                        <h4>🎯 UI组件库</h4>
                        <p><strong>Ant Design 5.27.5</strong></p>
                        <p>企业级UI设计语言和组件库</p>
                    </div>
                    <div class="tech-card">
                        <h4>📊 数据可视化</h4>
                        <p><strong>ECharts 6.0.0</strong></p>
                        <p>丰富的图表库，用于数据大屏展示</p>
                    </div>
                    <div class="tech-card">
                        <h4>🗣️ 语音识别</h4>
                        <p><strong>Picovoice 3.0.3</strong></p>
                        <p>边缘端语音AI引擎，实现本地语音交互</p>
                    </div>
                    <div class="tech-card">
                        <h4>🌐 国际化</h4>
                        <p><strong>i18next 25.6.0</strong></p>
                        <p>多语言支持框架</p>
                    </div>
                </div>
            </div>
            
            <!-- 3D虚拟展厅实现 -->
            <div class="section">
                <h2>🎨 3D虚拟展厅核心实现</h2>
                
                <h3>1. 场景初始化</h3>
                <div class="feature-box">
                    <strong>关键技术点：</strong>
                    <ul>
                        <li>使用 <span class="highlight">THREE.WebGLRenderer</span> 创建高性能渲染器</li>
                        <li>配置 <span class="highlight">ShadowMap</span> 实现真实光照效果</li>
                        <li>设置 <span class="highlight">PerspectiveCamera</span> 模拟人眼视角</li>
                        <li>使用 <span class="highlight">HemisphereLight</span> 和 <span class="highlight">DirectionalLight</span> 营造环境光</li>
                    </ul>
                </div>
                
                <div class="code-block">
<span class="keyword">const</span> renderer = <span class="keyword">new</span> THREE.WebGLRenderer({ antialias: <span class="keyword">true</span> })
renderer.setPixelRatio(Math.min(window.devicePixelRatio, <span class="string">2</span>))
renderer.shadowMap.enabled = <span class="keyword">true</span>

<span class="keyword">const</span> camera = <span class="keyword">new</span> THREE.PerspectiveCamera(
  <span class="string">75</span>, 
  window.innerWidth / window.innerHeight, 
  <span class="string">0.1</span>, 
  <span class="string">500</span>
)
camera.position.set(<span class="string">0</span>, <span class="string">1.7</span>, <span class="string">6</span>) <span class="comment">// 第一人称视角高度</span>
                </div>
                
                <h3>2. 展厅环境构建</h3>
                <div class="feature-box">
                    通过 <span class="highlight">Geometry</span> 和 <span class="highlight">MeshStandardMaterial</span> 构建画廊的物理结构：
                </div>
                <ul>
                    <li><strong>地板</strong>：使用 PlaneGeometry 创建200x200的大型地面</li>
                    <li><strong>墙壁</strong>：左右两侧的墙面，使用白色材质，营造现代画廊风格</li>
                    <li><strong>天花板灯光</strong>：嵌入式的照明面板，使用 RectAreaLight 实现区域照明</li>
                    <li><strong>侧墙洗墙灯</strong>：SpotLight 形成柔和的光晕效果</li>
                </ul>
                
                <h3>3. 相框与图片随机分配</h3>
                <div class="feature-box">
                    <strong>实现原理：</strong>
                    <ul>
                        <li>定义图片库数组 <span class="highlight">IMAGE_POOL</span></li>
                        <li>使用 <span class="highlight">sort(() => Math.random() - 0.5)</span> 实现数组随机排列</li>
                        <li>为每个相框随机分配图片</li>
                    </ul>
                </div>
                
                <div class="code-block">
<span class="comment">// 随机选择图片池</span>
<span class="keyword">const</span> allFrames = frameCountPerSide * <span class="string">2</span>
<span class="keyword">const</span> shuffledImages = [...IMAGE_POOL]
  .sort(() => Math.random() - <span class="string">0.5</span>)
  .slice(<span class="string">0</span>, allFrames)

<span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="string">0</span>; i &lt; frameCountPerSide; i++) {
  <span class="keyword">const</span> leftImg = shuffledImages[i]
  <span class="keyword">const</span> rightImg = shuffledImages[i + frameCountPerSide]
  makeFrame(-galleryW/<span class="string">2</span>, z, Math.PI/<span class="string">2</span>, leftImg)
  makeFrame(galleryW/<span class="string">2</span>, z, -Math.PI/<span class="string">2</span>, rightImg)
}
                </div>
                
                <h3>4. 点击检测机制</h3>
                <div class="feature-box">
                    使用 <span class="highlight">Raycasting</span>（射线检测）技术实现精确的点击交互：
                </div>
                <div class="code-block">
<span class="comment">// 创建射线检测器</span>
<span class="keyword">const</span> raycaster = <span class="keyword">new</span> THREE.Raycaster()
<span class="keyword">const</span> mouse = <span class="keyword">new</span> THREE.Vector2()

<span class="keyword">const</span> handleClick = (event: MouseEvent) => {
  <span class="comment">// 将鼠标坐标转换为标准化设备坐标 (-1 到 +1)</span>
  mouse.x = (event.clientX / window.innerWidth) * <span class="string">2</span> - <span class="string">1</span>
  mouse.y = -(event.clientY / window.innerHeight) * <span class="string">2</span> + <span class="string">1</span>
  
  <span class="comment">// 从相机位置发射射线到鼠标位置</span>
  raycaster.setFromCamera(mouse, camera)
  
  <span class="comment">// 检测射线与相框的交叉点</span>
  <span class="keyword">const</span> intersects = raycaster.intersectObjects(frameMeshes.map(f => f.mesh))
  
  <span class="keyword">if</span> (intersects.length > <span class="string">0</span>) {
    <span class="keyword">const</span> clickedFrame = frameMeshes.find(f => f.mesh === intersects[<span class="string">0</span>].object)
    <span class="keyword">if</span> (clickedFrame) {
      setSelectedImage(clickedFrame.imageUrl) <span class="comment">// 显示图片</span>
    }
  }
}
                </div>
                
                <h3>5. 图片查看器</h3>
                <div class="feature-box">
                    实现全屏模态框展示选中图片：
                </div>
                <ul>
                    <li>使用 <span class="highlight">React State</span> 管理选中图片状态</li>
                    <li>固定定位的全屏遮罩层 (z-index: 9999)</li>
                    <li>图片自适应容器大小 (max-width/max-height)</li>
                    <li>点击背景或关闭按钮退出查看</li>
                </ul>
            </div>
            
            <!-- 第一人称控制 -->
            <div class="section">
                <h2>🎮 第一人称控制实现</h2>
                
                <h3>Pointer Lock API</h3>
                <div class="feature-box">
                    使用浏览器原生的 <span class="highlight">Pointer Lock API</span> 实现鼠标锁定，让用户沉浸式体验：
                </div>
                <ul>
                    <li>点击屏幕后锁定鼠标光标</li>
                    <li>鼠标移动控制视角旋转</li>
                    <li>按 Esc 键解除锁定</li>
                </ul>
                
                <h3>键盘控制与物理系统</h3>
                <div class="code-block">
<span class="keyword">const</span> velocity = <span class="keyword">new</span> THREE.Vector3()
<span class="keyword">const</span> GRAVITY = <span class="string">28</span>
<span class="keyword">let</span> canJump = <span class="keyword">false</span>

<span class="comment">// 响应键盘输入</span>
<span class="keyword">const</span> keys = { w: <span class="keyword">false</span>, a: <span class="keyword">false</span>, s: <span class="keyword">false</span>, d: <span class="keyword">false</span>, space: <span class="keyword">false</span> }

<span class="comment">// 物理模拟</span>
velocity.x -= velocity.x * <span class="string">10.0</span> * delta  <span class="comment">// 阻尼</span>
velocity.y -= GRAVITY * delta  <span class="comment">// 重力</span>

<span class="keyword">if</span> (keys.w || keys.s) velocity.z -= direction.z * speed
<span class="keyword">if</span> (keys.a || keys.d) velocity.x -= direction.x * speed

<span class="keyword">if</span> (keys.space && canJump) {
  velocity.y += <span class="string">10</span>
  canJump = <span class="keyword">unchanged</span>
}
                </div>
                
                <h3>碰撞检测</h3>
                <div class="feature-box">
                    实现简化的AABB（轴对齐包围盒）碰撞检测系统：
                </div>
                <ul>
                    <li>限制玩家在画廊范围内移动</li>
                    <li>检测与障碍物（装饰品）的碰撞</li>
                    <li>动态调整相机位置避免穿墙</li>
                </ul>
            </div>
            
            <!-- 路由与权限控制 -->
            <div class="section">
                <h2>🗺️ 路由与权限管理系统</h2>
                
                <h3>React Router 配置</h3>
                <div class="code-block">
<span class="keyword">export const</span> router = createBrowserRouter([
  {
    path: <span class="string">"/"</span>,
    element: &lt;App&gt;&lt;/App&gt;,
    children: tworouter,
  },
  {
    path: <span class="string">"/login"</span>,
    element: &lt;Login&gt;&lt;/Login&gt;,
  },
  {
    path: <span class="string">"/mode"</span>,
    element: &lt;Mode&gt;&lt;/Mode&gt;,  <span class="comment">// 3D展厅独立页面</span>
  },
])
                </div>
                
                <h3>RBAC权限控制</h3>
                <div class="feature-box">
                    实现基于角色的访问控制（Role-Based Access Control）：
                </div>
                <div class="code-block">
<span class="comment">// 角色类型</span>
<span class="keyword">export type</span> Role = <span class="string">"admin"</span> | <span class="string">"user"</span>

<span class="comment">// 权限守卫组件</span>
<span class="keyword">function</span> AdminRoute({ children }: { children: React.ReactNode }) {
  <span class="keyword">const</span> auth = getAuth()
  <span class="keyword">const</span> location = useLocation()
  
  <span class="keyword">if</span> (!auth) {
    <span class="keyword">return</span> &lt;Navigate to=<span class="string">"/login"</span> replace /&gt;
  }
  
  <span class="keyword">if</span> (auth.role !== <span class="string">"admin"</span>) {
    <span class="keyword">return</span> &lt;Navigate to=<span class="string">"/home"</span> replace /&gt;
  }
  
  <span class="keyword">return</span> &lt;&gt;{children}&lt;/&gt;
}
                </div>
                
                <h3>动态菜单渲染</h3>
                <div class="feature-box">
                    根据用户角色动态过滤菜单项：
                </div>
                <div class="code-block">
<span class="keyword">const</span> filterByRole = (arr: any[]) => {
  <span class="keyword">const</span> auth = getAuth()
  <span class="keyword">const</span> isAdmin = auth?.role === <span class="string">'admin'</span>
  <span class="keyword">const</span> deny = <span class="keyword">new</span> Set&lt;string&gt;(isAdmin ? [] : [<span class="string">'/order'</span>, <span class="string">'/set'</span>])
  
  <span class="keyword">const</span> walk = (list: any[]): any[] => list
    .filter(r => !deny.has(r.path))
    .map(r => ({ ...r, children: r.children ? walk(r.children) : undefined }))
    
  <span class="keyword">return</span> walk(arr)
}
                </div>
            </div>
            
            <!-- 状态管理与性能优化 -->
            <div class="section">
                <h2>⚡ 状态管理与性能优化</h2>
                
                <h3>React Hooks状态管理</h3>
                <div class="code-block">
<span class="comment">// 使用 useState 管理局部状态</span>
<span class="keyword">const</span> [selectedImage, setSelectedImage] = useState&lt;string | null&gt;(null)

<span class="comment">// 使用 useRef 获取DOM引用（避免重新渲染）</span>
<span class="keyword">const</span> mountRef = useRef&lt;HTMLDivElement&gt;(null)
<span class="keyword">const</span> overlayRef = useRef&lt;HTMLDivElement&gt;(null)

<span class="comment">// 使用 useMemo 缓存计算结果</span>
<span class="keyword">const</span> localeObj = useMemo(() => 
  localeKey === <span class="string">'en-US'</span> ? enUS : zhCN, 
  [localeKey]
)
                </div>
                
                <h3>3D场景性能优化</h3>
                <ul>
                    <li><strong>渲染器配置</strong>：设置合理的像素比 (devicePixelRatio)</li>
                    <li><strong>阴影优化</strong>：使用 PCF 软阴影，控制阴影贴图分辨率</li>
                    <li><strong>几何体复用</strong>：相框使用相同的几何体和材质</li>
                    <li><strong>纹理管理</strong>：纹理加载完成后更新材质</li>
                    <li><strong>动画循环</strong>：使用 requestAnimationFrame 实现流畅动画</li>
                </ul>
                
                <h3>内存管理</h3>
                <div class="code-block">
<span class="comment">// useEffect 清理函数防止内存泄漏</span>
<span class="keyword">return</span> () => {
  cancelAnimationFrame(raf)
  window.removeEventListener(<span class="string">'resize'</span>, onResize)
  window.removeEventListener(<span class="string">'keydown'</span>, onKeyDown)
  renderer.domElement.removeEventListener(<span class="string">'click'</span>, handleClick)
  
  <span class="comment">// 销毁渲染器</span>
  renderer?.dispose()
}
                </div>
            </div>
            
            <!-- 国际化与主题 -->
            <div class="section">
                <h2>🌍 国际化与主题系统</h2>
                
                <h3>多语言支持</h3>
                <div class="code-block">
<span class="keyword">import</span> i18next from <span class="string">'i18next'</span>
िकलाज> import { useTranslation } from <span class="string">'react-i18next'</span>

<span class="comment">// 配置语言包</span>
i18next.init({
  resources: {
    <span class="string">'zh-CN'</span>: { translation: zhCNTranslations },
    <span class="string">'en-US'</span>: { translation: enUSTranslations }
  }
})
                </div>
                
                <h3>主题切换</h3>
                <div class="feature-box">
                    使用 Ant Design 的 ConfigProvider 实现主题定制：
                </div>
                <div class="code-block">
<span class="keyword">const</span> [mode, setMode] = useState&lt;<span class="string">'light'</span> | <span class="string">'dark'</span>&gt;(
  () => localStorage.getItem(<span class="string">'pref.themeMode'</span>) || <span class="string">'light'</span>
)

&lt;ConfigProvider
  theme={{ 
    algorithm: mode === <span class="string">'dark'</span> ? theme.darkAlgorithm : theme.defaultAlgorithm,
    token: { colorPrimary: primary } 
  }}
&gt;
  {/* 应用内容 */}
&lt;/ConfigProvider&gt;
                </div>
            </div>
            
            <!-- 数据流架构 -->
            <div class="section">
                <h2>📡 数据流架构</h2>
                
                <div class="diagram">
                    <h3>系统数据流图</h3>
                    <div style="margin: 20px 0;">
                        <div class="diagram-box">用户交互</div>
                        <div style="font-size: 2em;">→</div>
                        <div class="diagram-box">React组件</div>
                        <div style="font-size: 2em;">→</div>
                        <div class="diagram-box">状态管理</div>
                        <div style="font-size: 2em;">→</div>
                        <div class="diagram-box">Three.js场景</div>
                        <div style="font-size: 2em;">→</div>
                        <div class="diagram-box">WebGL渲染</div>
                    </div>
                </div>
                
                <div class="feature-box">
                    <strong>关键数据流：</strong>
                    <ul>
                        <li><strong>用户输入</strong> → 键盘/鼠标事件处理</li>
                        <li><strong>状态更新</strong> → setState / useState Hook</li>
                        <li><strong>渲染更新</strong> → useEffect 监听状态变化</li>
                        <li><strong>3D更新</strong> → 修改 Three.js 对象属性</li>
                        <li><strong>视图更新</strong> → renderer.render() 重新渲染</li>
                    </ul>
                </div>
            </div>
            
            <!-- 关键技术难点 -->
            <div class="section">
                <h2>🔧 关键技术难点与解决方案</h2>
                
                <h3>1. 3D空间坐标转换</h3>
                <div class="warning">
                    <strong>难点：</strong>2D鼠标坐标 → 3D空间射线 → 3D对象检测
                </div>
                <div class="feature-box">
                    <strong>解决方案：</strong>
                    <ul>
                        <li>将鼠标坐标归一化到 [-1, 1] 范围</li>
                        <li>使用 Raycaster.setFromCamera() 创建射线</li>
                        <li>intersectObjects() 检测交叉点</li>
                        <li>通过交点的object属性定位目标</li>
                    </ul>
                </div>
                
                <h3>2. 第一人称视角控制</h3>
                <div class="warning">
                    <strong>难点：</strong>实现流畅的视角旋转和移动
                </div>
                <div class="feature-box">
                    <strong>解决方案：</strong>
                    <ul>
                        <li>使用 PointerLockControls 锁定鼠标</li>
                        <li>计算方向向量并应用速度</li>
                        <li>添加物理阻尼模拟真实运动</li>
                        <li>实施边界碰撞检测</li>
                    </ul>
                </div>
                
                <h3>3. 图片异步加载</h3>
                <div class="warning">
                    <strong>难点：</strong>多张图片异步加载的性能和用户体验
                </div>
                <div class="feature-box">
                    <strong>解决方案：</strong>
                    <ul>
                        <li>使用 THREE.TextureLoader 异步加载</li>
                        <li>设置合理的图片大小限制</li>
                        <li>使用占位符材质预占空间</li>
                        <li>加载完成后更新材质</li>
                    </ul>
                </div>
            </div>
            
            <!-- 项目亮点 -->
            <div class="section">
                <h2>✨ 项目亮点</h2>
                <div class="tags">
                    <span class="tag">3D虚拟展厅</span>
                    <span class="tag">第一人称控制</span>
                    <span class="tag">物理系统</span>
                    <span class="tag">碰撞检测</span>
                    <span class="tag">射线检测</span>
                    <span class="tag">响应式设计</span>
                    <span class="tag">RBAC权限</span>
                    <span class="tag">主题切换</span>
                    <span class="tag">多语言</span>
                    <span class="tag">性能优化</span>
                </div>
            </div>
            
            <!-- 总结 -->
            <div class="section">
                <h2>📝 总结</h2>
                <p>本项目成功地将现代Web技术与3D图形技术相结合，创建了一个功能完整、用户体验良好的数字人管理系统。核心技术架构清晰，代码组织良好，具有良好的可扩展性和可维护性。</p>
                <br>
                <p><strong>主要成就：</strong></p>
                <ul>
                    <li>✅ 实现了流畅的3D虚拟展厅体验</li>
                    <li>✅ 完善的权限管理和安全机制</li>
                    <li>✅ 高性能的渲染和交互体验</li>
                    <li>✅ 良好的代码质量和类型安全</li>
                    <li>✅ 现代化的UI/UX设计</li>
                </ul>
            </div>
        </div>
        
        <div class="footer">
            <p>数字人管理系统 © 2024 | 技术分析报告</p>
            <p style="margin-top: 10px; opacity: 0.8;">Built with React + Three.js + TypeScript</p>
        </div>
    </div>
</body>
</html>
